#include"BlockQueue.hpp"
#include"Task.hpp"
#include<ctime>
#include<unistd.h>
#include<pthread.h>
#include<cstdlib>

using namespace std;

int Add(int x,int y)
{
    return x+y;
}

void* productor(void* args)
{
    BlockQueue<Task>* bq=(BlockQueue<Task>*)args;
    while(true)
    {
        int x=rand()%10+1;
        int y=rand()%5+1;
        Task t(x,y,Add);
        bq->push(t);
        cout<<pthread_self()<<"consumer:"<<t._x<<"+"<<t._y<<"="<<endl;
    }
}
void* consumer(void* args)
{
    BlockQueue<Task>* bq=(BlockQueue<Task>*)args;
    while(true)
    {
        Task t;
        bq->pop(&t);
        cout<<pthread_self()<<"produce:"<<t._x<<"+"<<t._y<<"="<<t()<<endl;
    }
}

int main()
{
    srand((uint64_t)time(nullptr)^getpid()^0xFF44);
    BlockQueue<Task>* bq=new BlockQueue<Task>();
    pthread_t c[2],p[2];
    pthread_create(c,nullptr,consumer,(void*)bq);
    pthread_create(c+1,nullptr,consumer,(void*)bq);
    pthread_create(p,nullptr,productor,(void*)bq);
    pthread_create(p+1,nullptr,productor,(void*)bq);

    pthread_join(c[0],nullptr);
    pthread_join(c[1],nullptr);
    pthread_join(c[0],nullptr);
    pthread_join(c[1],nullptr);

    delete bq;
    return 0;
}